package com.zja.www.view;

import com.zja.www.bean.Result;
import com.zja.www.controller.BaseController;
import com.zja.www.controller.UserController;
import com.zja.www.entity.Doctor;
import com.zja.www.entity.MedicalRecord;
import com.zja.www.entity.Schedule;
import com.zja.www.entity.User;
import com.zja.www.service.*;
        import com.zja.www.view.DepartmentView;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author ja
 * @create 2025/4/1
 * @description 用户界面类，处理用户交互
 */
public class UserView extends BaseController {

    private UserController userController;
    private User currentUser;
    private DepartmentService departmentService;
    private final ScheduleService scheduleService;
    private DepartmentView departmentView;


    public UserView(
            UserController userController,
            UserService userService,
            DoctorService doctorService,
            MedicalRecordService medicalRecordService,
            ScheduleService scheduleService,
            DepartmentService departmentService
            ) {
        super(userService, doctorService, medicalRecordService);
        this.userController = userController;
        this.scheduleService = scheduleService;
        this.departmentService = departmentService;
    }

    public void setDepartmentView(DepartmentView departmentView) {
        this.departmentView = departmentView;
    }

    /**
     * 显示学生主菜单
     */
    public void showStudentMenu() {
        System.out.println("\n======================学生界面==========================");
        System.out.println("1.注册");
        System.out.println("2.登录");
        System.out.println("0.返回主菜单");
        System.out.print("请选择：");

        int choice = readIntInput();
        switch (choice) {
            case 1:
                showRegisterInterface();
                break;
            case 2:
                showStudentLogin();
                break;
            case 0:
                return;
            default:
                System.out.println("无效的选择，请重新输入！");
                showStudentMenu();
        }
    }

    /**
     * 显示学生注册界面
     */
    private void showRegisterInterface() {
        System.out.println("\n====================学生注册界面========================");
        Result result = userController.handleRegister();
        System.out.println(result.getMessage()); // 显示注册结果
        showStudentMenu();
    }

    /**
     * 显示学生登录界面
     */
    public void showStudentLogin() {
        System.out.println("\n=====================学生登录界面==========================");
        Result result = userController.handleLogin();

        if (result.isSuccess()) {
            currentUser = (User) result.getData();

            // 检查 status 是否为 verified
            if (!"verified".equals(currentUser.getStatus())) {
                System.out.println("登录失败：您的账号尚未通过审核，请联系管理员！");
                currentUser = null;
                showStudentMenu();
                return;
            }

            System.out.println(result.getMessage());
            showHospitalSystem();
        } else {
            System.out.println(result.getMessage());
            showStudentMenu();
        }

    }

    /**
     * 显示校医院系统主菜单
     */
    public void showHospitalSystem() {
        System.out.println("\n=====================校医院系统=============================");
        System.out.println("1.预约挂号");
        System.out.println("2.查看历史预约记录");
        System.out.println("3.修改个人信息");
        System.out.println("0.退出登录(返回主菜单)");
        System.out.print("请选择：");

        int choice = readIntInput();
        switch (choice) {
            case 1:
                showAppointmentInterface();
                break;
            case 2:
                showAppointmentHistory();
                break;
            case 3:
                showPersonalInfoMenu();
                break;
            case 0:
                logout();
                break;
            default:
                System.out.println("无效的选择，请重新输入！");
                showHospitalSystem();
        }
    }

    /**
     * 显示预约挂号界面
     */
    private void showAppointmentInterface() {
        System.out.println("\n======================预约界面=======================");
        //  通过DepartmentView获取科室选择
        int departmentId = departmentView.showDepartmentSelection();

        //  处理选择结果
        if (departmentId == -1) {
            // 无可用科室情况
            System.out.println("系统暂无可预约科室，请联系管理员");
            showHospitalSystem();
        } else if (departmentId > 0) {
            // 有效选择
            handleAppointment(departmentId);
        }

    }

    /**
     * 显示历史预约记录
     */
    private void showAppointmentHistory() {
        System.out.println("\n==================历史预约记录==================");
        // 从数据库查询该用户的预约记录
        List<MedicalRecord> records = medicalRecordService.getRecordsByUser(currentUser.getId());

        if (records == null || records.isEmpty()) {
            System.out.println("暂无历史预约记录");
        } else {
            //  格式化显示记录
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

            for (int i = 0; i < records.size(); i++) {
                MedicalRecord record = records.get(i);
                Doctor doctor = doctorService.getDoctorById(record.getDoctorId());

                // 直接显示医生和科室信息（无需空值检查）
                System.out.printf("%d. %s %s %s (%s)\n",
                        i + 1,
                        dateFormat.format(record.getRecordTime()),
                        doctor.getDepartment(),
                        doctor.getName(),
                        record.getStatus());
            }
        }

        // 添加取消选项
        System.out.println("\n输入记录编号取消预约，或输入0返回");
        System.out.print("请选择：");

        int choice = readIntInput();
        if (choice > 0 && choice <= records.size()) {
            cancelAppointment(records.get(choice - 1));
        }
        showHospitalSystem();
    }

    /**
     * 显示个人信息菜单
     */
    private void showPersonalInfoMenu() {
        System.out.println("\n==============修改个人信息界面================");
        System.out.println("1.修改密码");
        System.out.println("2.修改手机号");
        System.out.println("3.注销账户");
        System.out.println("0.返回校医院系统");
        System.out.print("请选择：");

        int choice = readIntInput();
        switch (choice) {
            case 1:
                showChangePassword();
                break;
            case 2:
                showChangePhone();
                break;
            case 3:
                showDeleteAccount();
                break;
            case 0:
                showHospitalSystem();
                break;
            default:
                System.out.println("无效的选择！");
                showPersonalInfoMenu();
        }
    }

    /**
     * 显示修改密码界面
     */
    private void showChangePassword() {
        System.out.println("\n================修改密码界面==================");
        System.out.print("请输入当前密码：");
        String currentPassword = readStringInput();

        // 验证当前密码
        if (!currentPassword.equals(currentUser.getPassword())) {
            System.out.println("当前密码错误！");
            showPersonalInfoMenu();
            return;
        }

        System.out.print("请输入新密码：");
        String newPassword = readStringInput();
        System.out.print("再次确认密码：");
        String confirmPassword = readStringInput();

        if (!newPassword.equals(confirmPassword)) {
            System.out.println("您两次输入的密码不一致，是否重新输入(y/n)");
            String choice = readStringInput().toLowerCase();
            if (choice.equals("y")) {
                showChangePassword();
            } else {
                showPersonalInfoMenu();
            }
            return;
        }

        Result result = userController.updatePassword(currentUser.getId(), newPassword);
        if (result.isSuccess()) {
            currentUser.setPassword(newPassword); // 更新本地对象
            System.out.println("密码修改成功！");
        } else {
            System.out.println("密码修改失败：" + result.getMessage());
        }
        showPersonalInfoMenu();
    }

    /**
     * 显示修改手机号界面
     */
    private void showChangePhone() {
        System.out.println("\n================修改手机号界面==================");
        System.out.print("请输入新手机号：");
        String newPhone = readStringInput();


        Result result = userController.updatePhone(currentUser.getId(), newPhone);
        if (result.isSuccess()) {
            currentUser.setPhone(newPhone);
            System.out.println("修改手机号成功！");
        } else {
            System.out.println("修改手机号失败：" + result.getMessage());
        }
        showPersonalInfoMenu();
    }

    /**
     * 显示注销账户界面
     */
    private void showDeleteAccount() {
        System.out.println("\n================注销账户界面================");
        System.out.print("请输入您的密码确认注销：");
        String password = readStringInput();

        if (!password.equals(currentUser.getPassword())) {
            System.out.println("密码错误！");
            showPersonalInfoMenu();
            return;
        }

        System.out.print("确定要注销账户吗？此操作不可逆！(y/n)：");
        String confirm = readStringInput().toLowerCase();
        if (!confirm.equals("y")) {
            System.out.println("已取消注销操作");
            showPersonalInfoMenu();
            return;
        }

        Result result = userController.deleteUser(currentUser.getId());
        if (result.isSuccess()) {
            System.out.println("注销账户成功！");
            currentUser = null;
            showStudentMenu();
        } else {
            System.out.println("注销账户失败：" + result.getMessage());
            showPersonalInfoMenu();
        }
    }

    /**
     * 处理预约逻辑
     */
    private void handleAppointment(int departmentId) {

        //获取该科室医生列表
        List<Doctor> doctors = doctorService.getDoctorsByDepartmentId(departmentId);

        if (doctors == null || doctors.isEmpty()) {
            System.out.println("该科室暂无医生排班");
            showAppointmentInterface();
            return;
        }

        //  显示医生选择界面
        int doctorId = showDoctorSelection(doctors);
        if (doctorId > 0) {
            makeAppointment(departmentId, doctorId);
        }

        showHospitalSystem();
    }

    /**
     * 显示医生选择界面
     */
    private int showDoctorSelection(List<Doctor> doctors) {
        System.out.println("\n==== 可选医生 ====");
        for (int i = 0; i < doctors.size(); i++) {
            System.out.printf("%2d. %-10s %s\n",
                    i + 1,
                    doctors.get(i).getName(),
                    doctors.get(i).getPosition());
        }
        System.out.println(" 0. 取消预约");

        while (true) {
            System.out.print("请选择医生编号: ");
            int choice = readIntInput();
            if (choice >= 0 && choice <= doctors.size()) {
                return choice == 0 ? 0 : doctors.get(choice - 1).getId();
            }
            System.out.println("无效选择，请输入0~" + doctors.size());
        }
    }

    /**
     * 执行预约操作
     * @param departmentId 科室ID（用于验证）
     * @param doctorId 医生ID
     * @return 是否预约成功
     */
    private boolean makeAppointment(int departmentId, int doctorId) {
        try {
            // 验证医生所属科室
            Doctor doctor = doctorService.getDoctorById(doctorId);
            if (doctor == null || doctor.getDepartmentId() != departmentId) {
                System.out.println("医生信息无效或不属于该科室");
                return false;
            }


            // 获取当前用户
            User currentUser = getCurrentUser();
            if (currentUser == null) {
                System.out.println(" 用户未登录");
                return false;
            }

            // 选择预约时间
            Timestamp appointmentTime = selectAppointmentTime(doctorId);
            if (appointmentTime == null) {
                return false;
            }

            // 创建预约记录
            MedicalRecord record = new MedicalRecord();
            record.setUserId(currentUser.getId());
            record.setDoctorId(doctorId);
            record.setRecordTime(appointmentTime);
            record.setType(MedicalRecord.TYPE_APPOINTMENT);
            record.setStatus(MedicalRecord.STATUS_PENDING);

            boolean success = medicalRecordService.createRecord(record);
            if (success) {
                System.out.printf("\n 成功预约 %s 医生（%s）\n",
                        doctor.getName(),
                        formatDateTime(appointmentTime));
            }
            return success;

        } catch (Exception e) {
            System.err.println("预约过程中出错: " + e.getMessage());
            return false;
        }
    }

    /**
     * 选择预约时间
     */
    private Timestamp selectAppointmentTime(int doctorId) {
        // 获取医生可用时间段
        List<Timestamp> availableTimes = getDoctorAvailableTimes(doctorId);
        if (availableTimes.isEmpty()) {
            System.out.println(" 该医生近期无可用时段");
            return null;
        }

        // 显示可选时间
        System.out.println("\n==== 可约时段 ====");
        for (int i = 0; i < availableTimes.size(); i++) {
            System.out.printf("%2d. %s\n",
                    i + 1,
                    formatDateTime(availableTimes.get(i)));
        }

        // 处理用户选择
        while (true) {
            System.out.print("请选择时段编号（0取消）: ");
            int choice = readIntInput();
            if (choice == 0) return null;
            if (choice > 0 && choice <= availableTimes.size()) {
                return availableTimes.get(choice - 1);
            }
            System.out.println("无效选择，请输入0~" + availableTimes.size());
        }
    }

    /**
     * 格式化时间显示
     */
    private String formatDateTime(Timestamp timestamp) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm").format(timestamp);
    }

    private User getCurrentUser() {
        if (this.currentUser != null) {
            return this.currentUser;
        }
        return null;
    }


    /**
     * 获取医生可用时间段
     * @param doctorId 医生ID
     * @return 可用时间列表（按时间排序）
     */
    private List<Timestamp> getDoctorAvailableTimes(int doctorId) {
        // 获取医生排班
        List<Schedule> schedules = scheduleService.getSchedulesByDoctor(doctorId);

        // 获取已有预约
        Timestamp today = new Timestamp(System.currentTimeMillis());
        List<MedicalRecord> appointments = medicalRecordService.getRecordsByDoctorAndDate(doctorId, today);

        // 生成可用时段
        List<Timestamp> availableTimes = new ArrayList<>();
        for (Schedule schedule : schedules) {

                // 检查该排班是否还有空位
                if (schedule.getBookedAppointments() < schedule.getMaxAppointments()) {

                    availableTimes.add(combineDateTime(schedule.getDate(), schedule.getStartTime()));
                }
            }

        // 按时间排序
        availableTimes.sort(Timestamp::compareTo);
        return availableTimes;
    }

    /**
     * 合并日期和时间
     */
    private Timestamp combineDateTime(Timestamp date, String time) {
        try {
            SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
            Date timePart = timeFormat.parse(time);

            Calendar cal = Calendar.getInstance();
            cal.setTime(date);

            Calendar timeCal = Calendar.getInstance();
            timeCal.setTime(timePart);

            cal.set(Calendar.HOUR_OF_DAY, timeCal.get(Calendar.HOUR_OF_DAY));
            cal.set(Calendar.MINUTE, timeCal.get(Calendar.MINUTE));
            cal.set(Calendar.SECOND, 0);

            return new Timestamp(cal.getTimeInMillis());
        } catch (ParseException e) {
            throw new IllegalArgumentException("时间格式错误: " + time);
        }
    }

    /**
     * 检查两个时间戳是否为同一天
     */
    private boolean isSameDay(Timestamp ts1, Timestamp ts2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(ts1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(ts2);

        return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH) &&
                cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 取消预约
     * @param record 要取消的预约记录
     */
    private void cancelAppointment(MedicalRecord record) {
        // 检查预约状态是否允许取消
        if (!record.getStatus().equals(MedicalRecord.STATUS_PENDING)) {
            System.out.println("只有【待确认】状态的预约可以取消");
            return;
        }

        // 检查预约时间，至少提前2小时取消
        long diffHours = (record.getRecordTime().getTime() - System.currentTimeMillis()) / (60 * 60 * 1000);
        if (diffHours < 2) {
            System.out.println("距离预约时间不足2小时，无法取消");
            return;
        }

        System.out.print("确定要取消预约吗？(y/n): ");
        String confirm = readStringInput().toLowerCase();
        if (!confirm.equals("y")) {
            System.out.println("已取消操作");
            return;
        }

        // 执行取消操作
        boolean success = medicalRecordService.cancelRecord(record.getId());

        if (success) {
            scheduleService.cancelScheduleBooking(record.getDoctorId(), record.getRecordTime());
            System.out.println("预约取消成功");
        } else {
            System.out.println("取消失败，请稍后重试");
        }
    }

    /**
     * 退出当前用户登录
     */
    private void logout() {
        currentUser = null;
        System.out.println("已退出登录。");
        showStudentMenu();
    }
}
